package slog

import (
	"base/conf"
	"base/util/tools"
	"github.com/lestrrat-go/file-rotatelogs"
	"github.com/rifflock/lfshook"
	log "github.com/sirupsen/logrus"
	"io/ioutil"
	"os"
	"path"
	"time"
)

type LoggerDriver *log.Logger

var (
	logLevels = map[string]log.Level{
		"debug": log.DebugLevel,
		"info":  log.InfoLevel,
		"warn":  log.WarnLevel,
		"error": log.ErrorLevel,
		"fatal": log.FatalLevel,
		"panic": log.PanicLevel,
	}
	LogConf = conf.Conf.Logs
	Debug   = conf.Conf.Debug
	LoggerPool = map[string]*log.Logger{}
	Logger  = log.New()
)

func init() {
	//设置输出样式，自带的只有两种样式 logrus.JSONFormatter{}和 logrus.TextFormatter{}
	//设置output,默认为stderr,可以为任何io.Writer，比如文件*os.File
	level, ok := logLevels[LogConf.Level]
	if ok {
		Logger.SetLevel(level)
	} else {
		Logger.SetLevel(log.WarnLevel)
	}
	Logger.SetOutput(ioutil.Discard)
	if Debug {
		Logger.SetOutput(os.Stdout)
	}
	hook := newLfsHook()
	Logger.AddHook(hook)
}

func newLfsHook() log.Hook {
	abPath := tools.GetPwd()
	logName := path.Join(abPath, "log" , LogConf.Name)
	cstSh, _ := time.LoadLocation("Asia/Shanghai") //上海
	timeSuffix := time.Now().In(cstSh).Format("2006-01-02")
	writer, err := rotatelogs.New(
		logName+"."+timeSuffix,
		// WithLinkName为最新的日志建立软连接,以方便随着找到当前日志文件
		rotatelogs.WithLinkName(logName),

		// WithRotationTime设置日志分割的时间,这里设置为一小时分割一次
		rotatelogs.WithRotationTime(time.Duration(LogConf.RotationTime)*time.Hour),

		// WithMaxAge和 WithRotationCount二者只能设置一个,
		// WithMaxAge设置文件清理前的最长保存时间,
		// WithRotationCount设置文件清理前最多保存的个数.
		rotatelogs.WithMaxAge(time.Duration(LogConf.LogMaxAge)*time.Hour),
	)
	if err != nil {
		log.Errorf("config local file system for logger error: %v", err)
	}

	lfsHook := lfshook.NewHook(lfshook.WriterMap{
		log.DebugLevel: writer,
		log.InfoLevel:  writer,
		log.WarnLevel:  writer,
		log.ErrorLevel: writer,
		log.FatalLevel: writer,
		log.PanicLevel: writer,
	}, &log.JSONFormatter{
		TimestampFormat: "2006-01-02 15:04:05",
	})
	return lfsHook
}

func SetData(data map[string]interface{}) log.Fields {
	fields := log.Fields{}
	for k, v := range data {
		fields[k] = v
	}
	return fields
}
